package com.expert.service.Impl;

import com.expert.context.BaseContext;
import com.expert.enums.NoticeType;
import com.expert.enums.ProjectStatus;
import com.expert.exception.UpdateException;
import com.expert.pojo.*;
import com.expert.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @ClassName: TodoServiceImpl
 * @Author: cxs
 * @Date: 2024/03/29 23:00
 * @Description:
 **/
@Service
public class TodoServiceImpl implements TodoService {
    @Autowired
    ProjectService projectService;
    @Autowired
    ExtractResultService extractResultService;
    @Autowired
    ExpertService expertService;
    @Autowired
    NoticeService noticeService;
    @Autowired
    NoticeUserService noticeUserService;
    @Autowired
    ScoreDetailedService scoreDetailedService;

    /**
     * 获取未接受邀请的内容
     *
     * @return
     */
    @Override
    public List<Project> getInviteData() {
        Long id = BaseContext.getCurrentId();
        Expert expert = this.expertService.lambdaQuery().eq(Expert::getExpertUser, id).one();
        if (expert == null) {
            expert=new Expert();
        }

        List<ExtractResult> extractResultList = this.extractResultService.lambdaQuery()
                .eq(ExtractResult::getObsolete, 0)
                .eq(ExtractResult::getAcceptFlag,0)
                .eq(ExtractResult::getExpertId, expert.getId())
                .list();
        return extractResultList.stream().map(extractResult -> {
            Long projectId = extractResult.getProjectId();
            return this.projectService.getById(projectId);
        }).toList();
    }

    /**
     * 接受邀请
     *
     * @param id
     * @param accept
     */
    @Override
    public void accept(Long id, Integer accept) {
        Long userId = BaseContext.getCurrentId();
        Project project = this.projectService.getById(id);
        Expert expert = this.expertService.lambdaQuery().eq(Expert::getExpertUser, userId).one();
        ExtractResult extractResult = this.extractResultService.lambdaQuery()
                .eq(ExtractResult::getProjectId, id)
                .eq(ExtractResult::getExpertId, expert.getId())
                .eq(ExtractResult::getObsolete,0).one();
        if (accept==1){
            extractResult.setAcceptFlag(1);
            extractResult.setAcceptTime(LocalDateTime.now());
            this.extractResultService.updateById(extractResult);
            Long count = this.extractResultService.lambdaQuery().eq(ExtractResult::getProjectId, project.getId()).eq(ExtractResult::getAcceptFlag, 0).count();
            if (count==0){
                project.setProjectStatus(ProjectStatus.NOT_REVIEW.getCode());
            }
        }else {
            extractResult.setAcceptFlag(2);
            extractResult.setObsolete(1);
            this.extractResultService.updateById(extractResult);
            Notice notice=new Notice();
            notice.setNoticeType(NoticeType.USER.getCode());
            notice.setNoticeTitle("专家拒绝邀请通知");
            notice.setNoticeContent("专家"+expert.getExpertName()+"拒绝了项目《"+project.getProjectName()+"》的评审邀请。");
            notice.setCreateUser(BaseContext.getCurrentId());
            notice.setUpdateUser(BaseContext.getCurrentId());
            notice.setCreateTime(LocalDateTime.now());
            notice.setUpdateTime(LocalDateTime.now());
            this.noticeService.save(notice);
            NoticeUser noticeUser=new NoticeUser();
            noticeUser.setUserId(extractResult.getCreateUser());
            noticeUser.setNoticeId(notice.getId());
            this.noticeUserService.save(noticeUser);
        }
    }

    /**
     * 获取签到信息
     *
     * @return
     */
    @Override
    public List<Project> getAttendance() {
        Long id = BaseContext.getCurrentId();
        Expert expert = this.expertService.lambdaQuery().eq(Expert::getExpertUser, id).one();
        if (expert == null) {
            expert=new Expert();
        }
        List<ExtractResult> extractResultList = this.extractResultService.lambdaQuery()
                .eq(ExtractResult::getObsolete, 0)
                .eq(ExtractResult::getAcceptFlag,1)
                .eq(ExtractResult::getAttendanceFlag,0)
                .eq(ExtractResult::getExpertId, expert.getId())
                .list();
        return extractResultList.stream().map(extractResult -> this.projectService.getById(extractResult.getProjectId())).toList();
    }

    /**
     * 签到
     *
     * @param project
     * @param attendance
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void attendance(Long project, String attendance) {
        Long userId = BaseContext.getCurrentId();
        Project projects = this.projectService.getById(project);
        LocalDateTime minTime = projects.getProjectReviewTime().plusHours(-1);
        LocalDateTime maxTime=projects.getProjectReviewTime().plusHours(1);
        if (LocalDateTime.now().isBefore(minTime)||LocalDateTime.now().isAfter(maxTime)){
            throw new UpdateException("当前不在签到时间范围内，签到失败");
        }
        Expert expert = this.expertService.lambdaQuery().eq(Expert::getExpertUser, userId).one();
        ExtractResult extractResult = this.extractResultService.lambdaQuery()
                .eq(ExtractResult::getProjectId, project)
                .eq(ExtractResult::getExpertId, expert.getId())
                .eq(ExtractResult::getAcceptFlag,1)
                .eq(ExtractResult::getAttendanceFlag,0)
                .eq(ExtractResult::getObsolete,0).one();
        if (!extractResult.getAttendanceCode().equalsIgnoreCase(attendance)){
            throw  new UpdateException("签到码错误！");
        }
        projects.setProjectStatus(ProjectStatus.NOT_REVIEW.getCode());
        this.projectService.updateById(projects);
        extractResult.setAttendanceFlag(1);
        extractResult.setAttendanceTime(LocalDateTime.now());
        this.extractResultService.updateById(extractResult);
    }

    /**
     * 获取待评分内容
     *
     * @return
     */
    @Override
    public List<Project> getToScore() {
        Long userId=BaseContext.getCurrentId();
        Expert expert = this.expertService.lambdaQuery().eq(Expert::getExpertUser, userId).one();
        if (expert==null){
            expert=new Expert();
        }
        List<Long> projectList = this.scoreDetailedService.lambdaQuery()
                .eq(ScoreDetailed::getExpertId, expert.getId())
                .list().stream()
                .map(ScoreDetailed::getProjectId).toList();
        List<Project> resultList = this.extractResultService.lambdaQuery()
                .eq(ExtractResult::getExpertId, expert.getId())
                .eq(ExtractResult::getAttendanceFlag, 1)
                .notIn(!projectList.isEmpty(), ExtractResult::getProjectId, projectList)
                .list()
                .stream()
                .map(ExtractResult::getProjectId).toList().stream().map(id -> this.projectService.getById(id)).toList();

        return resultList;
    }
}
